/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.tom.social.analyzer.analysis;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocCollector;
import org.apache.lucene.search.similar.MoreLikeThis;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.getopt.stempel.lucene.StempelAnalyzer;
import org.openide.util.Exceptions;
import pl.tom.social.common.sitetool.ISiteTools;
import pl.tom.social.common.sitetool.SiteToolsFactory;
import pl.tom.social.dal.SocialDatabaseFacade;
import pl.tom.social.dal.entity.Site;
import pl.tom.social.dal.entity.SiteEntry;
import pl.tom.social.dal.utils.EntryIterator;

/**
 *
 * @author Tom
 */
public class SimilaritiesSearch {

	private static final Logger logger = Logger.getLogger(SimilaritiesSearch.class);

	public static Map<String, Float> getSimilar(SiteEntry entry, List<String> siteUrls, int limit) {
		Map<String, Float> result = new HashMap<String, Float>();
		try {
			SocialDatabaseFacade db = new SocialDatabaseFacade();
			ISiteTools tools = SiteToolsFactory.getTools(entry.getSiteId());

			Directory dir = FSDirectory.getDirectory("luceneDir");
			StempelAnalyzer analyzer = new StempelAnalyzer();
			IndexWriter iw = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
			for(String siteUrl : siteUrls) {
				try {
					Site site = db.getSite(siteUrl);
					for(Iterator iter = new EntryIterator(site); iter.hasNext();) {
						SiteEntry e = (SiteEntry) iter.next();
						Document doc = new Document();
						doc.add(new Field("url", e.getUrl(), Field.Store.YES, Field.Index.NO));
						doc.add(new Field("body", tools.getHtmlAsText(e.getBody()), Field.Store.NO, Field.Index.ANALYZED));
						iw.addDocument(doc);
					}
				} catch(Exception ex) {
					Exceptions.printStackTrace(ex);
				}
			}
			iw.close();

			IndexReader ir = IndexReader.open(dir);
			IndexSearcher is = new IndexSearcher(ir);
			Reader reader = new StringReader(tools.getHtmlAsText(entry.getBody()));
			try {
				MoreLikeThis mlt = new MoreLikeThis(ir);
				mlt.setFieldNames(new String[]{"body"});
				mlt.setMinDocFreq(0);
				mlt.setMinTermFreq(0);
				
				Query query = mlt.like(reader);
				TopDocCollector collector = new TopDocCollector(limit);
				is.search(query, collector);
				ScoreDoc[] hits = collector.topDocs().scoreDocs;
				for(int i = 0; i < hits.length; i++) {
					int docId = hits[i].doc;
					Document d = is.doc(docId);
					result.put(d.get("url"), hits[i].score);
				}
			} finally {
				ir.close();
				is.close();
				reader.close();
			}

		} catch(IOException ex) {
			logger.log(Level.ERROR, ex);
		}
		return result;
	}
}
